package com.xiangyueEducation.uploaderCloud.config;

import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.transaction.RabbitTransactionManager;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

import java.util.HashMap;
import java.util.Map;

@Configuration
@Slf4j
public class RabbitMQConfig implements RabbitTemplate.ConfirmCallback,RabbitTemplate.ReturnsCallback {


    //配置生成者端的事务管理
    @Bean
    public RabbitTransactionManager transactionManager(CachingConnectionFactory connectionFactory){
        return new RabbitTransactionManager(connectionFactory);
    }
    @Bean(name = "rabbitTemplateC")
    public RabbitTemplate rabbitTemplate(CachingConnectionFactory connectionFactory){
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setChannelTransacted(true);
        return rabbitTemplate;
    }

    //为rabbitMQ配置MessageConverter, 使其可以传输java对象
    @Bean
    public MessageConverter messageConverter() {
        return new Jackson2JsonMessageConverter();
    }

    @Resource(name = "rabbitTemplateC")
    RabbitTemplate rabbitTemplate;


    //信息可靠性传输保证(知道信息是否成功发送)
    @PostConstruct
    public void initRabbitTemplate() {
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnsCallback(this);
    }

    //信息是否被发送到交换机
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        log.info("消息发送确认情况:correlationData={}\n,ack={}\n,cause={}",correlationData,ack,cause);
    }

    //信息是否被发送到队列
    @Override
    public void returnedMessage(ReturnedMessage returned) {
        log.info("消息主体: "+new String(returned.getMessage().getBody()),
                "应答码: "+ returned.getReplyCode(),
                "描述: "+returned.getReplyText(),
                "交换机: "+returned.getExchange(),
                "路由键: "+returned.getRoutingKey());
    }

    //正常队列结合死信队列配置
    // 死信交换机和队列名称
    private static final String DEAD_EXCHANGE = "dead_letter_exchange";
    private static final String DEAD_QUEUE = "dead_letter_queue";

    // 正常交换机和队列名称
    private static final String NORMAL_EXCHANGE = "normal_exchange";
    private static final String NORMAL_QUEUE = "normal_queue";

    // 1️⃣ 创建死信交换机
    @Bean
    public DirectExchange deadLetterExchange() {
        return new DirectExchange(DEAD_EXCHANGE);
    }

    // 2️⃣ 创建死信队列
    @Bean
    public Queue deadLetterQueue() {
        return new Queue(DEAD_QUEUE);
    }

    // 3️⃣ 绑定死信交换机和死信队列
    @Bean
    public Binding deadLetterBinding() {
        return BindingBuilder.bind(deadLetterQueue()).to(deadLetterExchange()).with("dead_routing_key");
    }

    // 4️⃣ 创建正常交换机
    @Bean
    public DirectExchange normalExchange() {
        return new DirectExchange(NORMAL_EXCHANGE);
    }

    // 5️⃣ 创建正常队列，设置 TTL 和死信参数..(最重要的一步, 保证了正常队列与死信队列建立联系)
    @Bean
    public Queue normalQueue() {
        Map<String, Object> args = new HashMap<>();
        args.put("x-message-ttl", 600000); // TTL 10分钟（600000 毫秒）
        args.put("x-dead-letter-exchange", DEAD_EXCHANGE); // 超时后发送到死信交换机
        args.put("x-dead-letter-routing-key", "dead_routing_key"); // 死信路由键
        args.put("x-max-length", 5); // 队列最大长度，超出后溢出消息进入死信队列

        return new Queue(NORMAL_QUEUE, true, false, false, args);
    }

    // 6️⃣ 绑定正常交换机和队列
    @Bean
    public Binding normalBinding() {
        return BindingBuilder.bind(normalQueue()).to(normalExchange()).with("normal_routing_key");
    }

//
////    @Bean
//    public RabbitListenerContainerFactory<?> rabbitListenerContainerFactory(SimpleRabbitListenerContainerFactory factory) {
//        factory.setMessageConverter(messageConverter());
//        return factory;
//    }
//
//
//
//    @Bean(name = "u2uChatExchange")
//    public DirectExchange directExchange() {
//        return new DirectExchange("u2uChat-exchange");
//    }
//
//
//    //批量导入
//    @Bean(name = "batchImportExchange")
//    public DirectExchange batchImportDirectExchange() {
//        return new DirectExchange("batchImport-exchange");
//    }
//
//
//
//    @Bean
//    public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
//        System.out.println(connectionFactory);
//        return new RabbitAdmin(connectionFactory);
//    }



}
